<!-- 自动缩放文字大小组件，缩放后没有超出父组件大小则执行缩放，缩小后还是超过父组件大小则显示缩略号 -->
<template>
	<view ref="zoom" class="auto-zoom">
		<span class="text" ref="textRef">
			<slot></slot>
		</span>
	</view>
</template>

<script lang="ts" setup>
	import { onMounted, Ref, ref, defineProps, toRefs, watch } from 'vue';

	interface IAutoZoomTextProps {
		// text : string;
		distance ?: number;
		maxScale ?: number;
	}

	const props = withDefaults(defineProps<IAutoZoomTextProps>(), {
		//字间距
		distance: 0,
		//最大缩放值
		maxScale: .3,
	})

	const { distance, maxScale } = toRefs(props);


	const zoom = ref(null);

	const text : Ref<string> = ref('');

	const textRef = ref(null);


	onMounted(() => {
		text.value = childToText(zoom.value!.$slots.default()[0]);
		reset();
	})





	watch(text, (newVal, oldVal) => {
		if (!newVal || newVal == oldVal) return
		reset();
	}, {
		deep: true
	})




	const childToText = (children : any) : string => {
		if (children instanceof Array) {
			return (children.map(item => childToText(item))).join('')
		} else if (children instanceof Object) {
			if (children.default) {
				return childToText(children.default())
			} else {
				return childToText(children.children);
			}
		} else if (typeof children === 'string') {
			return children
		} else {
			return ''
		}
	}


	const reset = () => {
		//父元素
		const dom = zoom.value!.$el;
		//span组件
		const span = dom.children[0];
		//span下的所有子组件都变成inline-block形式
		for (let item of span.children) {
			item.style.display = 'inline-block';
		}
		//span宽度
		const spanWidth = dom.children[0].offsetWidth;
		//父元素宽度
		const lay = dom.offsetWidth;
		//每个文本的宽度
		const average = spanWidth / text.value.split("").length;
		//span宽度大于父组件宽度时执行缩放
		if (spanWidth + average * distance.value > lay) {
			//要缩小的百分比
			const s = (lay - average * distance.value) / spanWidth;
			//和maxScale比对，如果超过maxScale则取maxScale
			const finalS = s <= maxScale.value ? maxScale.value : s;
			//span标签缩放后实际的长度
			// const spanActualWidth = uni.getWindowInfo().screenWidth * (spanWidth - spanWidth * finalS) / 750;
			const spanActualWidth = spanWidth * finalS;
			//span缩放后没有比父元素大，按照缩放显示
			if (spanActualWidth <= lay) {
				const w = uni.getWindowInfo().screenWidth * (spanWidth - (spanWidth / finalS)) / 750;
				const finalW = w > 100 ? Math.ceil(w / 10) * 10 : w;
				span.style.display = 'inline-block';
				span.style.transform = `scale(${finalS}) translateX(${finalW}px)`;
			} else {
				//span缩放后比父元素大，按照显示缩略号显示
			}
		}
		span.addEventListener('DOMCharacterDataModified', () => {
			// console.log('DOMCharacterDataModified');
			text.value = childToText(zoom.value!.$slots.default()[0]);
		})
	}
</script>

<style scoped lang="scss">
	@import "./style.scss";
</style>